/*package net.mysoft.budgetsoft.system.dao.impl;
 
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import net.mysoft.budgetsoft.system.dao.FlowDao;
import net.mysoft.budgetsoft.system.domain.TFlow;
import net.mysoft.budgetsoft.system.domain.TFlowTaskNode;
import net.mysoft.budgetsoft.system.domain.TFlowTemplate;
import net.mysoft.budgetsoft.system.domain.TFlowTemplateNode;
import net.mysoft.budgetsoft.system.domain.TXiTongXX;
import net.mysoft.budgetsoft.system.domain.TYongHu;
import net.mysoft.budgetsoft.system.pagemodel.FlowOperationNote;
import net.mysoft.budgetsoft.system.pagemodel.YongHu;
import net.mysoft.framework.base.BaseDaoImpl;
import net.mysoft.framework.base.BaseFlowPageModel;
import net.mysoft.framework.exception.FlowStatusException;
import net.mysoft.framework.model.SessionInfo;
import net.mysoft.framework.util.CalendarUtil;
import net.mysoft.framework.util.ResourceUtil;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

*//**   
 *  
 * @author dagongPGP v1.0 
 * @link <a href=http://www.dagongsoft.net>北京大公信软科技有限公司</a> 
 *  
 * @version $Revision: 1.00  $Date: 2013-07-08 17:25:41 
 *//*   
@Repository("flowDao")
public class FlowDaoImpl extends BaseDaoImpl implements FlowDao{
	
	private static final Logger logger = Logger.getLogger(FlowDaoImpl.class);
	private static Date date;
	static {
		CalendarUtil tt = new CalendarUtil();
		SimpleDateFormat sdg = new SimpleDateFormat("yyyyMMdd");
		try {
			date = sdg.parse("20130101");
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
	
	*//**
	 * 流程实例化
	 *//*
	@Override
	public Map create(TFlowTemplate flowTemplate,String renWuJBXXBH,String xiangMuJBXXBH,String userCodes) { 
		Map map = new HashMap();
		SessionInfo sessionInfo = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
		TFlow t = new TFlow();
		t.setFlo_CreateTime(new Date());
		t.setFlo_Creator(sessionInfo.getUserId());
		t.setFlowTemplate(flowTemplate);
	//	t.setFLO_LastUpDateTime(); //上一步完成时间
		t.setFlo_Status(0);//状态 为 未完成
		t.setXiangMuJBXXBH(xiangMuJBXXBH);
		Serializable flo_ID = this.save(t); //新增流程实例
		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
			TXiangMuFlow  xf = new TXiangMuFlow(xiangMuJBXXBH,flo_ID.toString(),flowTemplate.getFtl_ID());
			this.save(xf);
		}
		Set<TFlowTemplateNode> set = flowTemplate.getFlowTemplateNodeSet();
		Iterator<TFlowTemplateNode> ite = set.iterator();
		while(ite.hasNext()){
			TFlowTemplateNode ftn = ite.next();
			if(ftn.getFtn_State()==1){//获得开始节点
				List list = new ArrayList(); 
				list.add(ftn);
				if(userCodes==null||"".equals(userCodes)){
					ftn.userCodes = sessionInfo.getUserId();
				}
				List<String> ftn_IDList = startNext(t,null,list,null,TFlow.RESULT_PASS,renWuJBXXBH,xiangMuJBXXBH);
				map.put("ftn_IDList", ftn_IDList);
			}
		}
		map.put("flo_ID", t.getFlo_ID());
		return map;
	}
	
	*//**
	 * 私有方法
	 * 
	 * 启动任务节点实例
	 * @param flow
	 * @param flowNode
	 * @return
	 *//*
	private List<String> startNext(TFlow flow,TFlowTaskNode ftn,List<TFlowTemplateNode> flowTemplateNodeList,String handlePrompt,int handleResult,String renWuJBXXBH,String xiangMuJBXXBH){
		logger.info("startNext:flow="+flow+".flowTemplateNodeList="+flowTemplateNodeList+".handlePrompt="+handlePrompt+".renWuJBXXBH="+renWuJBXXBH+".xiangMuJBXXBH="+xiangMuJBXXBH);
		System.out.println("startNext:flow="+flow+".flowTemplateNodeList="+flowTemplateNodeList+"flowTemplateNodeList.size()="+flowTemplateNodeList.size()+".handlePrompt="+handlePrompt+".renWuJBXXBH="+renWuJBXXBH+".xiangMuJBXXBH="+xiangMuJBXXBH);
		TXiangMuJBXX xiangmu = null;
		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
			xiangmu = (TXiangMuJBXX) this.get(TXiangMuJBXX.class, xiangMuJBXXBH);
		}
		String xiangMuYCLX = getXiangMuYCLX(xiangmu);
		if(flowTemplateNodeList!=null&&flowTemplateNodeList.size()!=0){
			TFlowTemplateNode tfn = flowTemplateNodeList.get(0);
			System.out.println("tfn.getFtn_Name_cn()======================="+tfn.getFtn_Name_cn()+"tfn.getFtn_Name_cn()======================="+tfn.getFtn_XiangMuJD());
			if(tfn.getFtn_XiangMuJD()!=null&&!"".equals(tfn.getFtn_XiangMuJD())){//切换项目阶段
				if(xiangmu!=null){
					TXiangMuJBXX txm = (TXiangMuJBXX) this.get(TXiangMuJBXX.class, xiangmu.getBianHao());
					txm.setXiangMuJD(tfn.getFtn_XiangMuJD());
					this.update(txm);
				}
			}
		}

		List ftnoIdListList = new ArrayList();
		StringBuffer sb = new StringBuffer();
		int i=0;
		for(TFlowTemplateNode flowTemplateNode:flowTemplateNodeList){
			if(i>0)sb.append(",");
			i++;
			sb.append(flowTemplateNode.getFtn_ID());
			List list = new ArrayList();
			List<String> userCodeList = new ArrayList();
			String userCodes = flowTemplateNode.userCodes;
			if(userCodes==null||"".equals(userCodes)||"null".equals(userCodes)){  //如果没有指派人 
				userCodes = "";
				List<YongHu> userList = candidate(flowTemplateNode.getFtn_ID(),null); //获取备选人
				if(userList.size()==0){//没有指派人。并且没有备选人
					if(xiangmu!=null){
						userCodes += xiangmu.getXiangMuFZR().getBianHao();
						System.out.println("xiangmu.getXiangMuFZR().getBianHao()==========="+xiangmu.getXiangMuFZR().getBianHao()+"userCodes============="+userCodes);
						userCodeList.add(xiangmu.getXiangMuFZR().getBianHao());
					}
				}else{
					int temp=0;
					for(YongHu u:userList){
						if(temp>0)userCodes+=",";
						userCodes+=u.getBianHao();
						userCodeList.add(u.getBianHao());
						temp++;
					}
				}
			}else{
				String[] userCodeArr = userCodes.split(",");
				userCodeList = new ArrayList();
				userCodeList.addAll(Arrays.asList(userCodeArr));
			}
			
			Set h = new HashSet(userCodeList);  //去重    
			userCodeList.clear();      
			userCodeList.addAll(h);
			System.out.println("userCodeList.size()==================="+userCodeList.size());
			StringBuffer sbbUserCodes = new StringBuffer();
			for(String userCode : userCodeList){
				if(sbbUserCodes.length()>0)sbbUserCodes.append(",");
				sbbUserCodes.append(userCode);
			}
			
			for(String userCode : userCodeList){
				TFlowTaskNode ftno = new TFlowTaskNode(flow,flowTemplateNode,userCode,1,renWuJBXXBH,xiangMuJBXXBH); //建立下一步任务节点实例   1状态为待办
				ftno.setFtn_Assignee(sbbUserCodes.toString());
				ftno.setXiangMuYCLX(xiangMuYCLX);
				Serializable s = this.save(ftno);
				if(ftn!=null)	addHandlePrompt(handlePrompt,userCode,ftno,ftn,handleResult);
				list.add(s.toString());
				ftnoIdListList.add(s.toString());
			}
			setFlo_OperationNote(flow,flowTemplateNode,userCodes);//设置流程操作记录、用于退回
		}
		flow.setFlo_CurrNode(sb.toString());   
		this.update(flow);
		return ftnoIdListList;
	}
	
	private String getXiangMuYCLX(TXiangMuJBXX xiangmu){
		String xiangMuYCLX = "";
		if(xiangmu!=null){
			String xmyclxs = xiangmu.getXiangMuYCLXs();
			if(xmyclxs!=null&&xmyclxs.contains(",")){
				String[] temp = xmyclxs.split(",");
				xiangMuYCLX = temp[temp.length-1];
			}else{
				xiangMuYCLX = xmyclxs;
			}
		}
		if(xiangMuYCLX==null||"".equals(xiangMuYCLX)){
			xiangMuYCLX = TXiangMuJBXX.CHUPING+"-1";
		}
		return xiangMuYCLX;
	}
	
	*//**
	 * 获得任务备选人
	 * @param flowNode
	 * @return
	 *//*
	public List<YongHu> candidate(String templateNodeID,String userCodes){
		System.out.println("candidate:"+templateNodeID+"@@"+userCodes);
		if(templateNodeID==null)return null;
		String roleIds = null;
		String userIds = null;
		TFlowTemplateNode ftn = (TFlowTemplateNode) this.get(TFlowTemplateNode.class, templateNodeID);
		roleIds = ftn.getFtn_IndeptRoleCode();
		userIds = ftn.getFtn_IndeptUserCode();	
		if(userCodes!=null&&!"".equals(userCodes)){
			userIds = userCodes;
			userCodes = null;
		}
		if((userIds==null||"".equals(userIds))&&(roleIds==null||"".equals(roleIds))){
			return new ArrayList<YongHu>();
		}
		List<TYongHu> userList = new ArrayList<TYongHu>();
		StringBuffer hql = new StringBuffer("select distinct t from TYongHu as t left join fetch t.tYongHuJSSet as r where 1=1 ");
		List params = new ArrayList();

		boolean userb = false;
		boolean roleb = false;
		if(userIds!=null&&!"".equals(userIds)){
			userb = true;
		}
		if(roleIds!=null&&!"".equals(roleIds)){
			roleb = true;
		}
		if(userb){
			String[] userIdArr = null;
			userIdArr = userIds.split(",");
			hql.append(" and");
			if(roleb){
				hql.append("(");
			}
			hql.append(" t.bianHao in(");
			for(int i=0;i<userIdArr.length;i++){
				if(i!=0){
					hql.append(",");
				}
				hql.append("?");
				params.add(userIdArr[i]);
			}
			hql.append(")");
		}
		if(roleb){
			String[] roleIdArr = null;
			roleIdArr = roleIds.split(",");
			if(userb){
				hql.append(" or");
			}else{
				hql.append(" and");
			}
			if(!userb){
				hql.append("(");
			}
			hql.append(" r.tJueSe.bianHao in(");
			for(int i=0;i<roleIdArr.length;i++){
				if(i!=0){
					hql.append(",");
				}
				hql.append("?");
				params.add(roleIdArr[i]);
			}
			hql.append(")");
			if(!userb){
				hql.append(")");
			}
		}
		String conditonUserName = ServletActionContext.getRequest().getParameter("conditionUserName");
		if(conditonUserName!=null&&!"".equals(conditonUserName)){
			hql.append(" and t.xingMing like ? ");
			params.add("%"+conditonUserName+"%");
		}
		userList = this.find(hql.toString(),params);
		List list2 = new ArrayList();
		for(TYongHu tuser : userList){
			YongHu user = new YongHu();
			BeanUtils.copyProperties(tuser, user);
			list2.add(user);
		}
		System.out.println("备选人"+list2.size());
		return list2;
	}
	
	private void setFlo_OperationNote(TFlow tflo,TFlowTemplateNode tftn,String userCodes){
		System.out.println("setFlo_OperationNote:"+userCodes);
		String flo_OperationNode = tflo.getFlo_OperationNote();
		List list = new ArrayList();
		boolean temp = true;
		if(flo_OperationNode!=null&&!"".equals(flo_OperationNode)){
			JSONObject jsonObj = new JSONObject();
			List<JSONObject> o = (List) jsonObj.parse (flo_OperationNode);
			for(JSONObject jsonObject:o){
				FlowOperationNote fon = new FlowOperationNote();
				fon.setTemplateNodeID(jsonObject.getString("templateNodeID"));
				//fon.setHandleUserCodes(jsonObject.getString("handleUserCodes"));
				fon.setUserCodes(jsonObject.getString("userCodes"));
				if(fon.getTemplateNodeID()!=null&&tftn.getFtn_ID().equals(fon.getTemplateNodeID())){//需要设置的步骤 分派人
					temp = false;
					fon.setUserCodes(userCodes);
				}
				list.add(fon);
			}
		}
		if(temp){
			FlowOperationNote fon = new FlowOperationNote();
			fon.setTemplateNodeID(tftn.getFtn_ID());
			fon.setUserCodes(userCodes);
			list.add(fon);
		}
		String jsonStr = JSON.toJSONStringWithDateFormat(list, "yyyy-MM-dd HH:mm:ss" );
		System.out.println(jsonStr);
		tflo.setFlo_OperationNote(jsonStr);
		this.update(tflo);
	}

	*//**
	 * 完成任务节点 （转下一步、直接完成）
	 * 1.送审要经过下一步节点选择  持有节点id 和被选人
	 * 2.一般完成任务 需要知道任务节点id （可以经过下一步节点选择或者不经过下一步节点选择，不选择下一步节点，会把当前任务的子节点创建并发的任务并且会按照该节点的备选人每人建立一条任务）
	 *//*
	@Override
	public List complete(BaseFlowPageModel baseFlowPageModel) throws FlowStatusException{
		List<String> ftnoIdListList = new ArrayList<String>();
		try{
			String ftn_ID = baseFlowPageModel.getFtn_ID();
			String templateNode_ID = baseFlowPageModel.getTemplateNode_ID();
			String userCodes = baseFlowPageModel.getFln_UserCode();
			System.out.println("ftn_ID=========================="+ftn_ID);
			TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class,ftn_ID);//任务节点
			if(ftn==null){
				throw new FlowStatusException("该任务节点已完成");
			}
			if(ftn.getFtn_Status()==2){//已经完成
				throw new FlowStatusException("该任务已完成");
			}
			TFlow tflo = ftn.getFlow();
			List<TFlowTemplateNode> flowTemplateNodeList = new ArrayList();//下一步节点list
			if(templateNode_ID==null||"".equals(templateNode_ID)){//下一步的节点ID 如果为空说明未经过下一步节点的选择  有可能下一步并发多个节点
				flowTemplateNodeList=findNextFlowTemplateNodeByFtn_ID(ftn_ID,0);
			}else{//下一步的节点已选择 
				TFlowTemplateNode flowTemplateNode = (TFlowTemplateNode) this.get(TFlowTemplateNode.class,templateNode_ID);
				flowTemplateNode.userCodes = userCodes;//设置节点的处理人 逗号分隔
				flowTemplateNodeList.add(flowTemplateNode);
			}
		
			logger.info("baseFlowPageModel.getFtnMissionsCompleted():"+baseFlowPageModel.getFtnMissionsCompleted());
			boolean isTemplateNodeComplete = setStatus(ftn_ID,tflo,TFlow.RESULT_PASS,baseFlowPageModel.getFtnMissionsCompleted());//状态判断是否完成    流程实例、流程节点
			logger.info("任务节点完成判断"+isTemplateNodeComplete);
			System.out.println("任务节点完成判断"+isTemplateNodeComplete);
			if(isTemplateNodeComplete){
				ftnoIdListList = startNext(tflo,ftn,flowTemplateNodeList,baseFlowPageModel.getHandlePrompt(),TFlow.RESULT_PASS,baseFlowPageModel.getRenWuJBXXBH(),baseFlowPageModel.getXiangMuBH());//启动下一步任务节点实例
			}
		}catch (Exception e) {
			e.printStackTrace();
			throw new FlowStatusException(e);
		}
		//throw new FlowStatusException();
		return ftnoIdListList;
	}
	
	*//**
	 * 根据任务节点实例查下一步节点 
	 * @param ftn_ID
	 * @return
	 *//*
	@Override
	public List<TFlowTemplateNode> findNextFlowTemplateNodeByFtn_ID(String ftn_ID,int lineStart){
		logger.info("findNextFlowTemplateNodeByFtn_ID:ftn_ID="+ftn_ID+".lineStart="+lineStart);
		System.out.println("findNextFlowTemplateNodeByFtn_ID:ftn_ID====================="+ftn_ID+".lineStart=================="+lineStart);
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class,ftn_ID);
		TFlowTemplateNode TFlowTemplateNode = ftn.getFlowTemplateNode();
		List<TFlowTemplateNode> list = findNextFlowTemplateNodeByTemplateNode_PID(TFlowTemplateNode.getFtn_ID());
		if(lineStart==1){
			if(list.size()==1){//跳过送审步骤
				TFlowTemplateNode tfn = list.get(0);
				return findNextFlowTemplateNodeByTemplateNode_PID(tfn.getFtn_ID());
			}
		}
		System.out.println("List<TFlowTemplateNode> list.size()=========================="+list.size());
		return list;
	}
	
	*//**
	 * 私有方法
	 * 
	 * 状态判断是否完成     流程实例、流程节点
	 *//*
	private boolean setStatus(String ftn_ID,TFlow tflo,int handleResult,int ftnMissionsCompleted){
		SessionInfo sessionInfo = (SessionInfo)ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
		boolean isFLNComplete = true; //流程节点是否完成
		boolean isFLOComplete = false; //流程实例是否完成
		TFlowTaskNode ftn = (TFlowTaskNode) this.load(TFlowTaskNode.class, ftn_ID);
		TFlowTemplateNode tfn = ftn.getFlowTemplateNode();
		Integer ftn_UsernNum = ftn.getFtn_UserNum();
		List<TFlowTaskNode> quanbuList = this.find("from TFlowTaskNode t where t.flow.flo_ID = ? and t.flowTemplateNode = ? and t.xiangMuYCLX = ?" , new Object[]{ftn.getFlow().getFlo_ID(),tfn,ftn.getXiangMuYCLX()});
		List<TFlowTaskNode> yiwanList = new ArrayList();
		List<TFlowTaskNode> weiwanList = new ArrayList();
		List<TFlowTaskNode> tongguoList = new ArrayList();
		for(TFlowTaskNode tftn : quanbuList){
			if(tftn.getFtn_ID().equals(ftn.getFtn_ID())){
				tftn.setFtn_HandleResult(handleResult);//通过
				tftn.setFtn_Status(TFlow.STATUS_FINISH);//状态
				tftn.setFtn_HandleEndTime(new Date());//处理时间
				tftn.setFtn_HandleUserCode(sessionInfo.getUserId());//处理人
				this.update(tftn);
			}
			if(tftn.getFtn_Status()!=null&&tftn.getFtn_Status()==1){
				weiwanList.add(tftn);
			}else if(tftn.getFtn_Status()!=null&&tftn.getFtn_Status()==2){
				yiwanList.add(tftn);
			}
			if(tftn.getFtn_HandleResult()!=null&&tftn.getFtn_HandleResult()==1){
				tongguoList.add(tftn);
			}
		}

		if(ftn.getFlowNodeClass()!=null){//送审 步骤class 小于0 只要一个完成删除其他task
			if(Integer.parseInt(ftn.getFlowNodeClass().getFnc_ID())<0){
				System.out.println("是送审步骤删除其他待办！");
				this.delete(weiwanList);
				ftn_UsernNum = 1;
			}
		}
		System.out.println("模板设置人数："+ftn_UsernNum+"已通过的人数:"+tongguoList.size());
		if(ftn_UsernNum==null||ftn_UsernNum==0){//如果未指定人数 有一个任务未完成 节点就未完成 否则按指定人数判断是否完成
			if(weiwanList.size()>0)
				isFLNComplete = false;
		}else{
			if(tongguoList.size()>=ftn_UsernNum){//如果确定已完成 删除该任务的其他待办
				for(TFlowTaskNode tftn:weiwanList){
					this.delete(tftn);
				}
			}else{
				if(weiwanList.size()>0)
					isFLNComplete = false;
			}
		}
		if(isFLNComplete){//如果节点已完成
			for(TFlowTaskNode tFlowTaskNode : yiwanList){
				TFlowTaskNode_His ftn_h = new TFlowTaskNode_His(tFlowTaskNode);
				this.save(ftn_h);
				this.delete(tFlowTaskNode);
			}
			if(tfn.getFtn_State()==2){////如果最后一步完成 流程实例完成
				isFLOComplete = true;
			}
		}
		System.out.println("任务节点"+isFLNComplete+"完成");
		if(isFLOComplete){
			tflo.setFlo_Status(2);
			tflo.setFlo_LastUpDateTime(new Date());
			this.update(tflo);
		}
		return isFLNComplete;
	}
	
	public List<TFlowTemplateNode> findNextFlowTemplateNodeByTemplateNode_PID(String ftn_PID){
		return this.find("from TFlowTemplateNode t where t.ftn_PID like ?",new String[]{"%"+ftn_PID+"%"});
	}
	
	*//**
	 * 根据任务节点实例查下一步节点 
	 * @param ftn_ID
	 * @return
	 *//*
	@Override
	public List<TFlowTemplateNode> findBackFlowTemplateNodeByFtn_ID(String ftn_ID,String templateNode_ID){
		List list =new ArrayList();
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class,ftn_ID);
		String templateNode_PID = null;
		TFlowTemplateNode tfn = ftn.getFlowTemplateNode();
		if(templateNode_ID!=null&&!"".equals(templateNode_ID)){//经过指派  
			templateNode_PID = templateNode_ID;
			TFlowTemplateNode temp = (TFlowTemplateNode) this.get(TFlowTemplateNode.class, templateNode_PID);
		}else{//未经过指派  查流程定义
			String returnTo = ftn.getFtn_ReturnTo();
			if(returnTo!=null&&!"".equals(returnTo)){//流程定义中设置了的
				templateNode_PID = returnTo;
			}else{//流程定义中未设置
				templateNode_PID = ftn.getFln_PID();
			}
		}
		list.add(this.get(TFlowTemplateNode.class, templateNode_PID));
		return list;
	}
	
	@Override
	public List<YongHu> backUpCandidate(String templateNodeID,String ftn_ID) {
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class, ftn_ID);
		String jsonStr = ftn.getFlow().getFlo_OperationNote();
		String userCodes = null;
		if(jsonStr!=null&&!"".equals(jsonStr)){
			JSONObject jsonObj = new JSONObject();
			List<JSONObject> o = (List) jsonObj.parse (jsonStr);
			for(JSONObject fon:o){
				if(templateNodeID.equals(fon.getString("templateNodeID"))){
					userCodes = fon.getString("userCodes");
					break;
				}
			}
		}
		return candidate(templateNodeID,userCodes);
	}
	
	@Override
	public List<String> skip(BaseFlowPageModel baseFlowPageModel) {
		logger.info("流程跳转skip();");
		String ftn_ID = baseFlowPageModel.getFtn_ID();
		String templateNode_ID = baseFlowPageModel.getTemplateNode_ID();
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class, ftn_ID);
		if(ftn==null){
			throw new FlowStatusException("该任务节点已完成");
		}
		if(ftn.getFtn_Status()==2){//已经完成
			throw new FlowStatusException("该任务已完成");
		}
		List<TFlowTemplateNode> ftList = findBackFlowTemplateNodeByFtn_ID(ftn.getFtn_ID(),templateNode_ID);
		String templateNode_PID = ftList.get(0).getFtn_ID();
		
		setStatus(ftn.getFtn_ID(),ftn.getFlow(),TFlow.RESULT_PASS,1);//最后一个参数1 有一个人退回 删除同一步骤下的其他tasknode
	
		List tFlowTaskNodeList = this.find("from TFlowTaskNode t where t.ftn_Status = 1 and t.xiangMuJBXXBH = ?",new String[]{baseFlowPageModel.getXiangMuBH()});//删除其他待办任务
		this.delete(tFlowTaskNodeList);
	
		logger.info("templateNode_PID："+templateNode_PID);
		//启动任务
		List nextFlowTemplateNodelist = new ArrayList();
		TFlowTemplateNode parenTFlowTemplateNode = (TFlowTemplateNode) this.get(TFlowTemplateNode.class, templateNode_PID);
		nextFlowTemplateNodelist.add(parenTFlowTemplateNode);
		return startNext(ftn.getFlow(),ftn,nextFlowTemplateNodelist,baseFlowPageModel.getHandlePrompt(),TFlow.RESULT_PASS,baseFlowPageModel.getRenWuJBXXBH(),baseFlowPageModel.getXiangMuBH());
	}
	
	*//**
	 * 任务退回       未完成的任务删除 保留当前任务和已完成任务                                      
	 * 
	 * 如果想要删除当前节点完成的部分任务 需要单独编码
	 * 注意：调用退回方法之前要写业务补偿（上会完成不能退回,立项不能退回,分支中不能退回）
	 *//*
	public List<String> sendBack(BaseFlowPageModel baseFlowPageModel){
		String ftn_ID = baseFlowPageModel.getFtn_ID();
		String templateNode_ID = baseFlowPageModel.getTemplateNode_ID();
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class, ftn_ID);
		if(ftn==null){
			throw new FlowStatusException("该任务节点已完成");
		}
		if(ftn.getFtn_Status()==2){//已经完成
			throw new FlowStatusException("该任务已完成");
		}
		String templateNode_PID = sendBack(ftn,templateNode_ID);
		//启动任务
		List nextFlowTemplateNodelist = new ArrayList();
		TFlowTemplateNode parenTFlowTemplateNode = (TFlowTemplateNode) this.get(TFlowTemplateNode.class, templateNode_PID);
		parenTFlowTemplateNode.userCodes = baseFlowPageModel.getFln_UserCode();
		nextFlowTemplateNodelist.add(parenTFlowTemplateNode);
		return startNext(ftn.getFlow(),ftn,nextFlowTemplateNodelist,baseFlowPageModel.getHandlePrompt(),TFlow.RESULT_SEND_BACK,baseFlowPageModel.getRenWuJBXXBH(),baseFlowPageModel.getXiangMuBH());
	}
	
	*//**
	 * 任务退回       未完成的任务删除 保留当前任务和已完成任务                                      
	 * 
	 * 如果想要删除当前节点完成的部分任务 需要单独编码
	 * 注意：调用退回方法之前要写业务补偿（上会完成不能退回,立项不能退回,分支中不能退回）
	 *//*
	public void sendBack_NotStartNext(BaseFlowPageModel baseFlowPageModel){
		String ftn_ID = baseFlowPageModel.getFtn_ID();
		String templateNode_ID = baseFlowPageModel.getTemplateNode_ID();
		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class, ftn_ID);
		if(ftn==null){
			throw new FlowStatusException("该任务节点已完成");
		}
		if(ftn.getFtn_Status()==2){//已经完成
			throw new FlowStatusException("该任务已完成");
		}
		String templateNode_PID = sendBack(ftn,templateNode_ID);
	}
	
	
	private String sendBack(TFlowTaskNode ftn,String templateNode_ID){
		TFlowTemplateNode tfn = ftn.getFlowTemplateNode();
		List<TFlowTemplateNode> ftList = findBackFlowTemplateNodeByFtn_ID(ftn.getFtn_ID(),templateNode_ID);
		setStatus(ftn.getFtn_ID(),ftn.getFlow(),TFlow.RESULT_SEND_BACK,1);//最后一个参数1 有一个人退回 删除同一步骤下的其他tasknode
		List<TFlowTemplateNode> flowTemplateNodeList = findNextFlowTemplateNodeByTemplateNode_PID(tfn.getFtn_PID());//多分支任务一个子节点退回。其他子节点任务同时删除
		for(TFlowTemplateNode fn:flowTemplateNodeList){
			List list = this.find(" from TFlowTaskNode t where t.flow.flo_ID = ? and t.flowTemplateNode = ? and t.ftn_Status !=2",new Object[]{ftn.getFlow().getFlo_ID(),fn});
			this.delete(list);
		}
		String templateNode_PID = ftList.get(0).getFtn_ID();
		return templateNode_PID;
	}
	
	
	*//**
	 * 添加办理提示
	 * "提示您：【"+qiYeMCs[i]+"】的"+"【"+buZhouNames[i]+"】请尽快处理！"
	 *//*
	public void addHandlePrompt(String neirong,String userCode,TFlowTaskNode daiBanftn,TFlowTaskNode yiBanftn,int handleResult){
		logger.info("添加系统提示！");
		try{
			SessionInfo sessionInfo = (SessionInfo)ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
			String s = "系统提示:";
			if(daiBanftn!=null){
				String xiangmubh = daiBanftn.getXiangMuJBXXBH();
				if(xiangmubh!=null&&!"".equals(xiangmubh)){
					TXiangMuJBXX t = (TXiangMuJBXX) this.get(TXiangMuJBXX.class, xiangmubh);
					if(t!=null&&t.getXiangMuMC()!=null&&!"null".equals(t.getXiangMuMC())){
						s += "【"+t.getXiangMuMC()+"】的";
						System.out.println("t.getXiangMuMC():"+t.getXiangMuMC());
					}
				}
			}
			if(yiBanftn!=null){
				s += "【"+yiBanftn.getFtn_Name_cn()+"】";
				if(TFlow.RESULT_PASS==handleResult){
					s += "已经通过";
				}else{
					s += "被退回";
				}
			}
			if(!s.equals("系统提示:")){
				if(daiBanftn!=null){
					s += "，请尽快处理【"+daiBanftn.getFtn_Name_cn()+"】！";
				}
				if(neirong!=null&&!"".equals(neirong)){
					s += sessionInfo.getUserName()+"提示您:" + neirong;
				}
				TXiTongXX t = new TXiTongXX();
				t.setBianHao(UUID.randomUUID().toString());
				t.setFromId(sessionInfo.getUserId());
				t.setToId(userCode);
				t.setNeiRong(s);
				t.setZhuangTai(TXiTongXX.WEIYUE);
				t.setShiJian(new Date());
				this.save(t);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	
	@Override
	public Map create_QianYi(TFlowTemplate flowTemplate, String renWuJBXXBH, String xiangMuJBXXBH, String userCodes,int shanghuiPSR_Num) {
		int tempLX = 1;
		if(xiangMuJBXXBH!=null &&!"".equals(xiangMuJBXXBH)){
			TXiangMuJBXX xiangmu = (TXiangMuJBXX) this.get(TXiangMuJBXX.class, xiangMuJBXXBH);
			if(xiangmu.getXiangMuLX()!=null&&xiangmu.getXiangMuLX()==101){
				tempLX = TXiangMuJBXX.GENZONG;
			}else{
				tempLX = TXiangMuJBXX.CHUPING;
			}
		}
		
		Map map = new HashMap();
		//SessionInfo sessionInfo = (SessionInfo) ServletActionContext.getRequest().getSession().getAttribute(ResourceUtil.getSessionInfoName());
		TFlow t = new TFlow();
		t.setFlo_CreateTime(date);
		t.setFlo_Creator("YongHu00000000000");
		t.setFlowTemplate(flowTemplate);
		t.setFlo_Status(0);//状态 为 未完成
		
		t.setXiangMuJBXXBH(xiangMuJBXXBH);
		Serializable flo_ID = this.save(t); //新增流程实例
		System.out.println(flo_ID+"@@@@@@@@@@");
		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
			TXiangMuFlow  xf = new TXiangMuFlow(xiangMuJBXXBH,flo_ID.toString(),flowTemplate.getFtl_ID());
			this.save(xf);
		}
		Set<TFlowTemplateNode> set = flowTemplate.getFlowTemplateNodeSet();
		System.out.println(set.size()+"@@@@@@@@@@");
		Iterator<TFlowTemplateNode> ite = set.iterator();
		
		while(ite.hasNext()){
			TFlowTemplateNode ftn = ite.next();
			List list = new ArrayList(); 
			list.add(ftn);
			if(userCodes==null||"".equals(userCodes)){
				ftn.userCodes = "YongHu00000000000";
			}
			List<String> ftn_IDList = startNext_QianYi(t,list,null,TFlow.RESULT_PASS,renWuJBXXBH,xiangMuJBXXBH,shanghuiPSR_Num,tempLX);
			map.put(ftn.getFtn_Name_cn(), ftn_IDList);
		}
		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
			TXiangMuJBXX txiangmu = (TXiangMuJBXX) this.get(TXiangMuJBXX.class, xiangMuJBXXBH);
			txiangmu.setXiangMuJD(306);
			this.update(txiangmu);
		}
		//map.put("flo_ID", t.getFlo_ID());
		return map;
	}*
	*//**
	 * 私有方法
	 * 
	 * 启动任务节点实例
	 * @param flow
	 * @param flowNode
	 * @return
	 *//*
	private List<String> startNext_QianYi(TFlow flow,List<TFlowTemplateNode> flowTemplateNodeList,String handlePrompt,int handleResult,String renWuJBXXBH,String xiangMuJBXXBH,int shanghuiPSR_Num,int tempLX){
		Collections.sort(flowTemplateNodeList,new FlowTemplateNodeComparator());
		List ftnoIdListList = new ArrayList();
		StringBuffer sb = new StringBuffer();
		int i=0;
		for(TFlowTemplateNode flowTemplateNode:flowTemplateNodeList){
			if(i>0)sb.append(",");
			i++;
			sb.append(flowTemplateNode.getFtn_ID());
			List list = new ArrayList();
			List<String> userCodeList = new ArrayList();
			String userCodes = flowTemplateNode.userCodes;
			
			if(shanghuiPSR_Num>1&&flowTemplateNode.getFtn_Name_cn().equals("上会评审")){
				for(int x=0;x<shanghuiPSR_Num;x++){
					TFlowTaskNode ftno = new TFlowTaskNode(flow,flowTemplateNode,"YongHu00000000000",2,renWuJBXXBH,xiangMuJBXXBH); //建立下一步任务节点实例   1状态为待办
					ftno.setFtn_HandleEndTime(date);
					ftno.setFtn_HandleResult(1);
					ftno.setFtn_Assignee("YongHu00000000000");
					ftno.setXiangMuYCLX(tempLX+"-1");
					Serializable s = this.save(ftno);
					TFlowTaskNode_His ftn_h = new TFlowTaskNode_His(ftno);
					this.save(ftn_h);
					this.delete(ftno);
					list.add(s.toString());
					ftnoIdListList.add(s.toString());
				}
			}else{
				TFlowTaskNode ftno = new TFlowTaskNode(flow,flowTemplateNode,"YongHu00000000000",2,renWuJBXXBH,xiangMuJBXXBH); //建立下一步任务节点实例   1状态为待办
				ftno.setFtn_HandleEndTime(date);
				ftno.setFtn_HandleResult(1);
				ftno.setFtn_Assignee("YongHu00000000000");
				ftno.setXiangMuYCLX(tempLX+"-1");
				Serializable s = this.save(ftno);
				TFlowTaskNode_His ftn_h = new TFlowTaskNode_His(ftno);
				this.save(ftn_h);
				this.delete(ftno);
				list.add(s.toString());
				ftnoIdListList.add(s.toString());
			}
		}
		flow.setFlo_CurrNode(sb.toString());       
		this.update(flow);
		return ftnoIdListList;
	}
	
	
	*//**
	 * 根据任务节点实例查下一步节点
	 * @param ftn_ID
	 * @return
	 *//*
//	@Override
//	public List<TFlowTemplateNode> findNextFlowTemplateNodeByTemplateNode_ID(String TemplateNode_ID){
//		TFlowTaskNode ftn = (TFlowTaskNode) this.get(TFlowTaskNode.class,TemplateNode_ID);
//		TFlowTemplateNode TFlowTemplateNode = ftn.getFlowTemplateNode();
//		return findNextFlowTemplateNodeByTemplateNode_ID(TFlowTemplateNode.getFtn_ID());
//	} 

	*//**
	 * 根据节点实例查下一步节点
	 * @param fln_ID
	 * @return
	 *//*
//	public List<TFlowTemplateNode> findNexTFlowTemplateNodeByFln_ID(String fln_ID){  
//		return this.find("from TFlowTemplateNode t where t.fln_PID like ?",new String[]{"%"+fln_ID+"%"});
//	}

	
	*//**
	 * 递归把当前任务到指派节点中的所有节点 更新成未办状态
	 *//*
	private void updateFln_Status(TFlowTemplateNode tt){
		*//**
		if(tt.getFln_Status()==2){
			tt.setFln_Status(0);
			tt.setFln_HandleTime(null);
			this.update(tt);
			List<TFlowTemplateNode> flowNodeList = findNexTFlowTemplateNodeByFln_PID(tt.getFln_ID());
			for(TFlowTemplateNode fn:flowNodeList){
				updateFln_Status(fn);
			}
		}**//*
	}
	

	*//**
	 * 任务暂停
	 *//*
//	public void taskNodePause(String xiangMuJBXXBH){
//		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
//			this.executeHql("update TFlowTaskNode t set t.ftn_Status = "+TFlow.STATUS_PAUSE+" where t.xiangMuJBXXBH = ?",new String[]{xiangMuJBXXBH});
//		}
//	}
	*//**
	 * 任务重新开始
	 *//*
//	public void taskNodeRenew(String xiangMuJBXXBH){
//		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
//			this.executeHql("update TFlowTaskNode t set t.ftn_Status = "+TFlow.STATUS_UNFINISHED+" where t.xiangMuJBXXBH = ?",new String[]{xiangMuJBXXBH});
//		}
//	}
	
	*//**
	 * 删除流程实例
	 *//*
	public void deleteFlow(String flowID){
		List list = this.find("from TFlowTaskNode t where t.flow.flo_ID = ?",new String[]{flowID});
		List list2 = this.find("from TFlowTaskNode_His t where t.flow.flo_ID = ?",new String[]{flowID});
		List list3 = this.find("from TFlow t where t.flo_ID = ?",new String[]{flowID});
		this.delete(list);
		this.delete(list2);
		this.delete(list3);
	}

	*//**
	 * 流程控制
	 *//*
	public void flowControl(String templateNode_ID,String xiangMuJBXXBH,String renWuJBXXBH){//删除待办  已送审改成未送审
		TFlowTemplateNode ftnt = (TFlowTemplateNode) this.get(TFlowTemplateNode.class, templateNode_ID); 
		List ftntList = new ArrayList();
		ftntList.add(ftnt);
		if(xiangMuJBXXBH!=null&&!"".equals(xiangMuJBXXBH)){
			List<TSongShenWJ> list = this.find("from TSongShenWJ where xiangmubh = ? and shenhezt = 2",new String[]{xiangMuJBXXBH});
			for(TSongShenWJ wj:list){
				wj.setShenHeZT(1);
				this.update(wj);
			}
			List<TFlowTaskNode> ftnList = this.find("from TFlowTaskNode where xiangMuJBXXBH = ?",new String[]{xiangMuJBXXBH});
			for(TFlowTaskNode t:ftnList){
				if(t.getFlowTemplateNode().getFlowTemplate().getFtl_ID().equals(ftnt.getFlowTemplate().getFtl_ID())){
					System.out.println(ftnt.getFtn_Name_cn()+"@@@"+renWuJBXXBH+"@@@"+xiangMuJBXXBH);
					
					startNext(t.getFlow(),null,ftntList,null,0,renWuJBXXBH,xiangMuJBXXBH);
					break;
				}
			}
			this.delete(ftnList);
			//找到最近的ftn 修改之后的ftn为失效状态
			List<TFlowTaskNode_His> list_His = this.find("from TFlowTaskNode_His as t where t.ftn_Status = 2 and t.flowTemplateNode = ? and t.xiangMuJBXXBH = ? order by t.ftn_HandleEndTime desc",new Object[]{ftnt,xiangMuJBXXBH});
			if(list_His.size()>0){
				TFlowTaskNode_His ftn_his = list_His.get(0);
				List<TFlowTaskNode_His> list_His2 = this.find("from TFlowTaskNode_His as t where t.ftn_Status = 2 and t.xiangMuJBXXBH = ? and t.ftn_HandleEndTime >= ? order by t.ftn_HandleEndTime desc",new Object[]{xiangMuJBXXBH,ftn_his.getFtn_HandleEndTime()});
				for(TFlowTaskNode_His t_his:list_His2){
					t_his.setFtn_Status(3);//设置为失效
					this.update(t_his);
				}
			}
		}else if(renWuJBXXBH!=null&&!"".equals(renWuJBXXBH)){
			List<TFlowTaskNode> ftnList = this.find("from TFlowTaskNode where renWuJBXXBH = ?",new String[]{renWuJBXXBH});
			for(TFlowTaskNode t:ftnList){
				if(t.getFlowTemplateNode().getFlowTemplate().getFtl_ID().equals(ftnt.getFlowTemplate().getFtl_ID())){
					System.out.println(ftnt.getFtn_Name_cn()+"@@@"+renWuJBXXBH+"@@@"+xiangMuJBXXBH);
					startNext(t.getFlow(),null,ftntList,null,0,renWuJBXXBH,xiangMuJBXXBH);
					break;
				}
			}
			this.delete(ftnList);
			//找到最近的ftn 修改之后的ftn为失效状态
			List<TFlowTaskNode_His> list_His = this.find("from TFlowTaskNode_His as t where t.ftn_Status = 2 and t.flowTemplateNode = ? and t.renWuJBXXBH = ? order by t.ftn_HandleEndTime desc",new Object[]{ftnt,renWuJBXXBH});
			if(list_His.size()>0){
				TFlowTaskNode_His ftn_his = list_His.get(0);
				List<TFlowTaskNode_His> list_His2 = this.find("from TFlowTaskNode_His as t where t.ftn_Status = 2 and t.renWuJBXXBH = ? and t.ftn_HandleEndTime >= ? order by t.ftn_HandleEndTime desc",new Object[]{renWuJBXXBH,ftn_his.getFtn_HandleEndTime()});
				for(TFlowTaskNode_His t_his:list_His2){
					t_his.setFtn_Status(3);//设置为失效
					this.update(t_his);
				}
			}
		}
	}

}  
*/